package com.apkcore.bl;

public class _33搜索旋转排序数组 {
    int[] nums;
    int target;

    /**
     * 查找一般用二分查找，O(logn)
     * 1 二分一般是有序的，当前数组是由有序旋转成的无序
     * 2 找到最小元素，就是旋转索引了
     * 3 通过旋转索引可以把数组分成两部分，比较nums[0]和target以确定哪个部分查找目标
     */
    public int search(int[] nums, int target) {
        this.nums = nums;
        this.target = target;
        int n = nums.length;
        if (n == 0) {
            return -1;
        }
        if (n == 1) {
            return this.nums[0] == target ? 0 : -1;
        }
        int rotate = findRotateIndex(0, n-1);

        if (nums[rotate] == target) {
            return rotate;
        }
        if (rotate == 0) {
            return search(0, n - 1);
        }
        if (target < nums[0]) {
            return search(rotate, n - 1);
        }
        return search(0, rotate);
    }

    public int findRotateIndex(int left, int right) {
        if (nums[left] < nums[right]) {
            return 0;
        }

        while (left <= right) {
            int pivot = (left + right) / 2;
            if (nums[pivot] > nums[pivot + 1]) {
                return pivot + 1;
            } else {
                if (nums[pivot] < nums[left]) {
                    right = pivot - 1;
                } else {
                    left = pivot + 1;
                }
            }
        }
        return 0;
    }

    public int search(int left, int right) {
        while (left <= right) {
            int pivot = (left + right) / 2;
            if (nums[pivot] == target) {
                return pivot;
            } else if (target < nums[pivot]) {
                right = pivot - 1;
            } else {
                left = pivot + 1;
            }
        }
        return -1;
    }
}